package com.jl15988.pguard.platform;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;

/**
 * Windows平台进程实现
 *
 * @author jl15988
 * @since 1.0.0
 */
@Slf4j
public class WindowsProcessPlatform implements ProcessPlatform {
    @Override
    public Process createProcess(String command, String workingDirectory, String[] environmentVariables) throws IOException {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("cmd", "/c", command);

        if (workingDirectory != null) {
            processBuilder.directory(new java.io.File(workingDirectory));
        }

        if (environmentVariables != null) {
            processBuilder.environment().putAll(java.util.Arrays.stream(environmentVariables)
                    .map(s -> s.split("="))
                    .collect(java.util.stream.Collectors.toMap(arr -> arr[0], arr -> arr[1])));
        }

        return processBuilder.start();
    }

    @Override
    public Process monitorProcess(long pid) throws IOException {
        return Runtime.getRuntime().exec(
                "cmd /c echo 监控进程 " + pid + " & " +
                        "typeperf \"\\Process(" + pid + ")\\*\" -si 1"
        );
    }

    @Override
    public boolean killProcess(long pid) throws InterruptedException, IOException {
        Process process = Runtime.getRuntime().exec("taskkill /F /PID " + pid);
        return process.waitFor(3000, TimeUnit.MILLISECONDS) &&
                process.exitValue() == 0;
    }

    @Override
    public boolean isProcessExist(long pid) {
        try {
            Process p = Runtime.getRuntime().exec(
                    String.format("cmd /c tasklist /FI \"PID eq %d\" /NH", pid)
            );

            try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
                return reader.lines().anyMatch(line -> line != null && !line.trim().isEmpty());
            }
        } catch (IOException e) {
            log.error("检查进程存在时发生错误", e);
            return false;
        }
    }

    @Override
    public long findProcessIdByPort(int port) {
        try {
            Process process = Runtime.getRuntime().exec("netstat -ano | findstr :" + port);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains("LISTENING")) {
                    String[] parts = line.trim().split("\\s+");
                    return Long.parseLong(parts[parts.length - 1]);
                }
            }
        } catch (Exception e) {
            log.error("查找Windows端口对应进程失败", e);
        }
        return -1;
    }

    @Override
    public String getPlatformName() {
        return "Windows";
    }

    @Override
    public PlatformProcessInfo getProcessInfo(long pid) throws IOException {
        Process p = Runtime.getRuntime().exec(
                "wmic process where ProcessId=" + pid +
                        " get WorkingSetSize,PercentProcessorTime /format:value"
        );

        double cpuUsage = 0;
        long memoryUsage = 0;

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("WorkingSetSize=")) {
                    memoryUsage = Long.parseLong(line.substring("WorkingSetSize=".length()).trim());
                } else if (line.startsWith("PercentProcessorTime=")) {
                    cpuUsage = Double.parseDouble(line.substring("PercentProcessorTime=".length()).trim());
                }
            }
        }

        return new PlatformProcessInfo(cpuUsage, memoryUsage);
    }
}
